package com.siemens.industrial.web.mvc.service.partner;

import com.siemens.industrial.model.partner.DeviceEventRelation;
import com.siemens.industrial.model.partner.Event;
import com.siemens.industrial.utils.GlobalResponseCode;
import com.siemens.industrial.utils.JsonToOtherFormat;
import com.siemens.industrial.utils.SiemensException;
import com.siemens.industrial.web.mvc.dao.partner.PartnerDeviceEventRelationDao;
import com.siemens.industrial.web.mvc.dao.partner.PartnerEventDao;
import com.siemens.industrial.web.mvc.pojo.DataTableQuery;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * Created by qupen on 2016/8/31.
 */
@Service
public class PartnerEventService {
    @Resource
    PartnerEventDao partnerEventDao;

    @Resource
    PartnerDeviceEventRelationDao partnerDeviceEventRelationDao;

    @Resource
    JdbcTemplate jdbcTemplate;

    public Event getEvent(String tenantId, String eventId) {
        return partnerEventDao.getEvent(tenantId, eventId);
    }

    public List<Event> getEvents(String tenantId) {
        return partnerEventDao.getEvents(tenantId);
    }

    @Transactional
    public void saveEvent(String tenantId, Event event) throws SiemensException {
        if (partnerEventDao.getEvent(tenantId, event.getEventId()) == null) {
            partnerEventDao.saveEvent(tenantId, event);
        } else {
            throw new SiemensException(GlobalResponseCode.ERROR_EVENT_EXISTED);
        }
    }

    @Transactional
    public void updateEvent(String tenantId, Map<String, Object> data) throws SiemensException {
        Event event = partnerEventDao.getEvent(tenantId, data.get("eventId").toString());
        if (event != null) {
            event.setEventId(data.get("eventId").toString());
            event.setEventType(data.get("type").toString());
            event.setEventDesc(data.get("description").toString());
            event.setEventTrigger(JsonToOtherFormat.buildJsonToString(data.get("trigger")));
            partnerEventDao.updateEvent(tenantId, event);
        } else {
            throw new SiemensException(GlobalResponseCode.ERROR_EVENT_NOT_EXISTED);
        }
    }

    @Transactional
    public void deleteEvent(String tenantId, String eventId) throws SiemensException {
        if (partnerEventDao.getEvent(tenantId, eventId) != null) {
            partnerEventDao.deleteEvent(tenantId, eventId);
        } else {
            throw new SiemensException(GlobalResponseCode.ERROR_EVENT_NOT_EXISTED);
        }
    }

    public List<Map<String, Object>> getEventSubscriptions(String tenantId) {
        return partnerEventDao.eventSubList(tenantId);
    }

    public List<Map<String, Object>> getEventSubscriptionsByDeviceId(String tenantId, String deviceId) {
        return partnerEventDao.getSubEventList(tenantId, deviceId);
    }

    @Transactional
    public void deleteEventAndRelation(String tenantId, String eventId) {
        partnerDeviceEventRelationDao.deleteRelation(tenantId, eventId);
        partnerEventDao.deleteEvent(tenantId, eventId);
    }

    public void saveDeviceEventRelation(String tenantId, Map<String, Object> data) {
        String subscription = data.get("subscription").toString();
        String mail = data.get("mail").toString();
        int type = Integer.parseInt(data.get("type").toString());
        List<String> events = (List<String>) data.get("event");
        for (int i = 0; i < events.size(); i++) {
            DeviceEventRelation deviceEventRelation = new DeviceEventRelation();
            deviceEventRelation.setEmail(mail);
            deviceEventRelation.setSubscription(subscription);
            deviceEventRelation.setEventId(events.get(i));
            deviceEventRelation.setType(type);
            partnerDeviceEventRelationDao.deleteDeviceEventRelation(tenantId, events.get(i), subscription, type);
            partnerDeviceEventRelationDao.saveDeviceEventRelation(tenantId, deviceEventRelation);
        }
    }

    public List<Map<String, Object>> getAllSubByEventId(String tenantId, String eventId) {
        List<Map<String, Object>> mtList = partnerDeviceEventRelationDao.getSubDevice(tenantId, eventId);
        List<Map<String, Object>> groupAndLineList = partnerDeviceEventRelationDao.getSubDeviceByType(tenantId, eventId);
        mtList.addAll(groupAndLineList);
        return mtList;
    }

    public void deleteEventAndRelationById(String tenantId, List<Map<String,Object>> params, String eventId) {
        for (Map<String,Object> map : params) {
            partnerDeviceEventRelationDao.deleteEventDeviceRelationByEventIdAndDeviceId(tenantId, Integer.parseInt(String.valueOf(map.get("type"))),String.valueOf(map.get("subscription")),eventId);
        }
    }

    public Event getOneByName(String tenantId, String eventName) {
        return partnerDeviceEventRelationDao.findOneByName(tenantId, eventName);
    }

    public Map<String, Object> getAllMailByEventIdAndDeviceId(String tenantId, String eventId) {
        return partnerDeviceEventRelationDao.getAllMail(tenantId, eventId);
    }

    public void insertMessage(String database, String eventId, int status, String mtid, String startTime, String endTime, String eventName) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start, end;
        try {
            start = simpleDateFormat.parse(startTime);
            end = simpleDateFormat.parse(endTime);
            partnerDeviceEventRelationDao.insertMessage(database, eventId, status, mtid, start, end, eventName);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public void updateMessageStatus(String database, String eventId, int status, String mtid, String startTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            partnerDeviceEventRelationDao.updateMessageStatus(database, eventId, status, mtid, simpleDateFormat.parse(startTime));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    //dataTable search events
    public Map<String, Object> getEventsByDataTable(String tenantId, HttpServletRequest request) {
        DataTableQuery dt = new DataTableQuery(request);
        List<Map<String, Object>> list = new ArrayList<>();

        String sql = "SELECT * FROM `" + tenantId + "`.`event` where 1=1\n";
        int total = jdbcTemplate.queryForList(sql).size();
        int filteredCount = total;
        if (!dt.getSearch().equals("")) {
            String search = " and (`event_name` like '%" + dt.getSearch() + "%' or `event_type` like '%" + dt.getSearch() + "%' or `event_desc` like '%" + dt.getSearch() + "%')";
            sql += search;
            filteredCount = jdbcTemplate.queryForList(sql).size();
        }
        if (!dt.getOrderDBColumn().equals("") && !dt.getOrderAscOrDesc().equals("")) {
            String order = " order by `" + dt.getOrderDBColumn() + "` " + dt.getOrderAscOrDesc() + "\n";
            sql += order;
        }

        String limit = " limit " + dt.getStart() + "," + dt.getLength();
        sql += limit;

        list = jdbcTemplate.queryForList(sql);
        return dt.buildResponse(filteredCount, total, list);
    }

    //dataTable search event subscriptions
    public Map<String, Object> getEventSubscriptionsByDataTable(String tenantId, HttpServletRequest request) {
        DataTableQuery dt = new DataTableQuery(request);
        List<Map<String, Object>> list = new ArrayList<>();

        String sql = "SELECT \n" +
                "    *\n" +
                "FROM\n" +
                "    (SELECT \n" +
                "    a.event_id,\n" +
                "    a.event_name,\n" +
                "    a.event_type,\n" +
                "    a.event_desc,\n" +
                "    GROUP_CONCAT(case when b.type=1 then (select d.device_unique_id from `" + tenantId + "`.device d where d.device_id=b.subscription) when b.type=2 then concat(b.subscription, '(组)') when b.type=3 then concat(b.subscription,'(流水线)') end) subscription\n" +
                "from `" + tenantId + "`.event AS a\n" +
                "        LEFT JOIN\n" +
                "        `" + tenantId + "`.device_event_relation b ON a.event_id = b.event_id\n" +
                "group by a.event_id) dt\n" +
                "WHERE 1 = 1\n";
        int total = jdbcTemplate.queryForList(sql).size();
        int filteredCount = total;

        if (!dt.getSearch().equals("")) {
            String search = " and (dt.event_id like binary '%" + dt.getSearch() + "%' or dt.event_name like binary '%" + dt.getSearch() + "%' or dt.event_type like binary '%" + dt.getSearch() + "%' or dt.event_desc like binary '%" + dt.getSearch() + "%' or dt.device_unique_id like binary '%" + dt.getSearch() + "%')";
            sql += search;
            filteredCount = jdbcTemplate.queryForList(sql).size();
        }

        if (!dt.getOrderDBColumn().equals("") && !dt.getOrderAscOrDesc().equals("")) {
            String order = " order by `" + dt.getOrderDBColumn() + "` " + dt.getOrderAscOrDesc();
            sql += order;
        }

        String limit = " limit " + dt.getStart() + "," + dt.getLength();
        sql += limit;
        list = jdbcTemplate.queryForList(sql);
        return dt.buildResponse(filteredCount, total, list);
    }

    public List<Map<String, Object>> getAllSubscriptionByType(String tenantId, String subscription, int type) {
        return partnerDeviceEventRelationDao.findAllSubscriptionByType(tenantId, subscription, type);
    }

    public String[] isSubscriptionTheEventByDeviceIdOrGroupOrLine(String tenantId, String eventId, String deviceId, String group, String line) {
        String sql = "SELECT DISTINCT `email` FROM `" + tenantId + "`.`device_event_relation` WHERE `event_id`='" + eventId + "'";
        sql += " AND (`subscription`='" + deviceId + "'";
        if (group != null && !group.equals("")) {
            sql += " OR `subscription`='" + group + "'";
        }
        if (line != null && !line.equals("")) {
            sql += " OR `subscription`='" + line + "'";
        }
        sql += ")";
        String[] mails = null;
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        if (maps.size() != 0) {
            mails = new String[maps.size()];
            for (int i = 0; i < maps.size(); i++) {
                String mail = String.valueOf(maps.get(i).get("email"));
                mails[i] = mail;
            }
        }
        return mails;
    }
}
